#import "BMList.h"
#import <objc/List.h>
#import <strings.h>
#import <appkit/NXImage.h>
#import <dpsclient/psops.h>
#import <dpsclient/wraps.h>
#import "MenuManager.h" 
// instances of this class represent
// a single instance of an NXImage.
// The class is used by BMShared_ to
// hold data for shared bitmaps.  
// Every time a bitmap is allocated,
// it is kept in a list.  Class records
// allow the list to be searched.
// If a bitmap with the same className
// and same size is found, it is returned,
// rather than a new instance, and the
// refCount is increased.  When an
// instance is freed, its refcount
// is decreased.  It is only "really"
// freed if its refcount reaches 0.

static id BMList_ = nil ;
@implementation BMList:Object
{ @public
  NXSize size ;
  char className[24] ;
  id image ;
  int refCount ;
}

+ show ;
{ // for verification: dump out BMList
  int i, count ;
  count = [BMList_ count] ;
  for(i = 0 ; i < count ; i++)
    [[BMList_ objectAt: i] show] ;
  return self ;
}

+ BitMapList ;
{ // give access to the list of instances
  return BMList_ ;
}

+ newForClass: (char *) aClass size: (NXSize *) aSize ;
{ int i, knt ;
  BMList *aBM ;
  if(!BMList_)
  { BMList_ = [[List alloc] init] ;
  }
  knt = [BMList_ count] ;
  for(i = 0 ; i < knt ; i++)
  { // search for bitmap of same size and class
    aBM = [BMList_ objectAt: i] ;
    if( (aBM->size.width == aSize->width) &&
        (aBM->size.height == aSize->height) &&
        (!strcmp(aBM->className, aClass)) )
    { // then we already have this bitMap
      aBM->refCount++ ;
      return aBM ;
    }  
  }
  // if we get here, then must create new bitmap
  return [[super alloc] initForClass: aClass size: aSize] ;
}

- initForClass: (char *) aClass size: (NXSize *) aSize ;
{ // make a new, transparent bitmap
  NXRect aRect = {{0.0,0.0},{0.0,0.0}} ;
  [super init] ;
  strcpy(className, aClass) ;
  size = aRect.size = *aSize ;
  refCount = 1 ;
  image = [[NXImage alloc] initSize: &aRect.size] ;
  [image lockFocus] ;
  PSgsave() ;
  NXEraseRect(&aRect) ;
  PSsetalpha(0.0) ;
  PSrectfill(0.0,0.0,size.width,size.height) ;
  PSgrestore() ;
  [image unlockFocus] ;
  [BMList_ addObject: self] ;
  return self ;
}

- (char *) className ;
{ return className ;
}

- free ;
{ // only "really" free if refCount == 0
  refCount-- ;
  if(refCount == 0)
  { [BMList_ removeObject: self] ;
    return [super free] ;
  }
  return self ;
}

- image ;
{ return image ;
}

- newRef ;
{ // increase my reference count
  refCount++ ;
  return self ;
}
- (int) refCount ;
{ return refCount ;
}

- show ;
{ // print my state
  [Nu printf: "classname = %s\n"
      "size= %f %f\n"
      "image= %s\n"
      "refcount= %d\n\n",
  className, size.width, size.height, image, refCount] ;
  return self ;
}

@end

